package cn.jichangxiu.way.filter;

import cn.jichangxiu.common.ucenter.model.AuthToken;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //从头取出jwt令牌
    public String getJwtFromHeader(ServerHttpRequest request) {
        //取出头信息
        String authorization = request.getQueryParams().getFirst("Authorization");
        if (StringUtils.isEmpty(authorization)) {
            return null;
        }
        if (!authorization.startsWith("Bearer ")) {
            return null;
        }
        //取到jwt令牌
        String jwt = authorization.substring(7);
        return jwt;
    }

    //从cookie取出token
    //查询身份令牌
    public String getTokenFromCookie(ServerHttpRequest request) {
        String accessToken = null;
        try {
            accessToken = request.getCookies().get("uid").get(0).getValue();
        }catch (NullPointerException e){

        }
        if (StringUtils.isEmpty(accessToken) || accessToken == null) {
            return null;
        }
        return accessToken;
    }

    //查询令牌的有效期
    public long getExpire(String accessToken) {
        //key
        String key = "accessToken:" + accessToken;
        Long expire = stringRedisTemplate.getExpire(key, TimeUnit.SECONDS);
        return expire;
    }

    public AuthToken getAuthToken(String accessToken) {
        String key = "accessToken:" + accessToken;
        String jsonToken = stringRedisTemplate.opsForValue().get(key);
        AuthToken authToken = JSON.parseObject(jsonToken, AuthToken.class);
        return authToken;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String accessToken = getTokenFromCookie(request);
        if (!StringUtils.isEmpty(accessToken)){
            long time = getExpire(accessToken);
            if (time > 0){
                AuthToken authToken = getAuthToken(accessToken);
                if (authToken != null){
                    String jwtToken = authToken.getJwtToken();
                    ServerHttpRequest build = exchange.getRequest().mutate().headers(httpHeaders -> {
                        httpHeaders.add("Authorization", "Bearer " + jwtToken);
                    }).build();
                    ServerWebExchange webExchange = exchange.mutate().request(build).build();
                    return chain.filter(webExchange);
                }
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
